﻿using System;
using System.Collections.Generic;
using System.Reflection;

namespace MugenInjection.Interface
{
    /// <summary>
    ///     The context for resolve binding.
    /// </summary>
    public interface IBindingContext
    {
        /// <summary>
        ///     Gets or sets the service type.
        /// </summary>
        Type Service { get; set; }

        /// <summary>
        ///     Gets the type into injected specified service <see cref="Service" />.
        /// </summary>
        Type TypeInto { get; }

        /// <summary>
        ///     Gets the <see cref="MemberInfo" /> that will receive the injection, if any.
        /// </summary>
        MemberInfo Member { get; }

        /// <summary>
        ///     Gets the <see cref="ParameterInfo" /> that will receive the injection, if any.
        /// </summary>
        ParameterInfo ParameterInfo { get; }

        /// <summary>
        ///     Gets the binding to activate, if any.
        /// </summary>
        IBinding Binding { get; set; }

        /// <summary>
        ///     Gets the <see cref="IInjector" /> to activate current context.
        /// </summary>
        IInjector Injector { get; set; }

        /// <summary>
        ///     Gets the <see cref="Injector" /> who called service activation.
        /// </summary>
        IInjector CallInjector { get; set; }

        /// <summary>
        ///     Gets the parameters.
        /// </summary>
        IList<IInjectionParameter> Parameters { get; set; }

        /// <summary>
        ///     Gets the special parameters.
        /// </summary>
        IDictionary<string, object> SpecialParameters { get; }

        /// <summary>
        ///     Gets or sets the parent binding context.
        /// </summary>
        IBindingContext ParentBindingContext { get; set; }

        /// <summary>
        ///     Updates the current <c>IBindingContext</c>.
        /// </summary>
        void Update(Type service, MemberInfo member, ParameterInfo parameterInfo, IInjector injector,
                    IInjector callInjector, IList<IInjectionParameter> parameters,
                    IDictionary<string, object> specialParameters);

        /// <summary>
        ///     Updates the current <see cref="IBindingContext" />.
        /// </summary>
        /// <param name="callInjector">The specified call injector.</param>
        /// <param name="injector">The specified injector.</param>
        void Update(IInjector callInjector, IInjector injector);

        /// <summary>
        ///     Gets the hash-code of values in the binding-context.
        /// </summary>
        /// <returns>The hash code of values.</returns>
        int GetSnapshot();
    }
}